package aiku.numericalcontroloa.Base.Exception;

import aiku.numericalcontroloa.Base.Utils.HttpStatus;
import aiku.numericalcontroloa.Base.Utils.Result;
import aiku.numericalcontroloa.common.constant.HttpStatusConstant;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * @ClassName com.example.chat_room.common.global
 * @Description
 * @Author Hardy
 * @Time 2023/12/05 01:07
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理未登录异常
     * @param e
     * @return
     */
    @ExceptionHandler(NotLoginException.class)
    public Result handleNotLoginException(NotLoginException e, HttpServletRequest request) {

        String path = request.getRequestURI();
        log.info("【未登录异常】 请求路径 ------> {}", path);

        // 返回信息
        String msg = "";

        switch (e.getType()) {
            case NotLoginException.NOT_TOKEN:
                msg = "未登录，请先登陆";
                break;
            case NotLoginException.TOKEN_TIMEOUT:
                msg = "登录已过期，请重新登陆";
                break;
            case NotLoginException.INVALID_TOKEN:
                msg = "登录错误，请重新登陆";
                break;
            case NotLoginException.BE_REPLACED:
                msg = "账号异地登录，请重新登录";
                break;
            case NotLoginException.TOKEN_FREEZE:
                msg = "账号已被冻结";
                break;
            default:
                msg = "当前会话未登录";
        }

        log.info("【响应】----> {}", msg);

        return new Result(HttpStatus.UNAUTHORIZED,msg);
    }

    /**
     * 处理权限不足异常
     * @param e
     * @param request
     * @return
     */
    @ExceptionHandler(NotPermissionException.class)
    public Result handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {
        log.info("【权限不足】 请求路径 ------> {}", request.getRequestURI());
        return Result.error("权限不足", HttpStatus.FORBIDDEN);
    }

    /**
     * 处理请求参数字段异常
     * @param e
     * @param request
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
        log.info("【入参校验异常】 请求路径 ------> {}", request.getRequestURI());

        // 打印具体错误日志
        e.printStackTrace();

        // 获取错误提示信息
        String msg = e.getBindingResult().getFieldError().getDefaultMessage();
        return Result.error(msg, HttpStatus.ARGS_ERROR);
    }

    // 处理params参数异常
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Result handleMissingServletRequestParameterException(Exception e, HttpServletRequest request) {
        log.info("【未处理异常】 请求路径 ------> {}", request.getRequestURI());

        // 打印具体错误日志
        e.printStackTrace();

        return Result.error("parma参数错误", HttpStatus.ARGS_ERROR);
    }

    /**
     * 处理文件上传异常
     * @param e
     * @param request
     * @return
     */
    @ExceptionHandler(FileUploadException.class)
    public Result handleFileUploadException(FileUploadException e, HttpServletRequest request) {
        log.info("【文件上传异常】 请求路径 ------> {}", request.getRequestURI());
        return Result.error(e.getMessage());
    }

    /**
     * 处理其他全局异常
     * @param e
     * @param request
     * @return
     */
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e, HttpServletRequest request) {
        log.error("【未处理异常】 请求路径 ------> {}", request.getRequestURI());

        // 打印具体错误日志
        e.printStackTrace();

        return Result.error("服务器内部错误", HttpStatusConstant.INTERNAL_SERVER_ERROR);
    }
}
